﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Activation;
using System.Web;
using System.Data.SqlClient;
using System.Data;
using BrokerBase.Lib.Client;
using Broker.Service.Model;
using Broker.Service.EntityModel;
using BrokerBase.Lib.Tool;
using BrokerBase.Lib.DataBase;

namespace Broker.Service
{
    // 注意: 使用“重构”菜单上的“重命名”命令，可以同时更改代码、svc 和配置文件中的类名“DataService”。
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class DataService : IDataService
    {

        public string IsNameExist(string name)
        {
            using (broker30Entities entity = new broker30Entities())
            {
                bool result = ClientUtil.IsNameExist(name,entity);

                return Newtonsoft.Json.JsonConvert.SerializeObject(result);
            }
        }

        public string Register(byte[] registrantInfoData, byte[] terminalInfoData, string activeCode)
        {
            //解析注册客户信息
            RegistrantInfo registranInfo = RegistrantInfo.Parse(registrantInfoData);
            //解析终端信息
            TerminalInfo terminalInfo = TerminalInfo.Parse(terminalInfoData);

            IDbTransaction tx = null;

            string message=string.Empty;

            ActiveResult ar = new ActiveResult();

            using (broker30Entities entity = new broker30Entities())
            {
                try
                {
                    entity.Connection.Open();

                    tx = entity.Connection.BeginTransaction();

                    Sale_ActiveCode code = ActiveCodeUtil.GetActiveCodeByVerify(activeCode, registranInfo, terminalInfo,entity,tx, out message);

                    ar.Description = message;

                    if (code != null)
                    {
                        OperationContext context = OperationContext.Current;
                        //获取传进的消息属性  
                        System.ServiceModel.Channels.MessageProperties properties = context.IncomingMessageProperties;
                        //获取消息发送的远程终结点IP和端口  
                        System.ServiceModel.Channels.RemoteEndpointMessageProperty endpoint = properties[System.ServiceModel.Channels.RemoteEndpointMessageProperty.Name] as System.ServiceModel.Channels.RemoteEndpointMessageProperty;

                        Sale_ActiveCodeReg reg = ActiveCodeUtil.Register(code, registranInfo, terminalInfo, endpoint.Address,entity,tx, out message);

                        tx.Commit();
                        if (reg != null)
                        {
                            string presenterName = null;
                            if (code.PresenterId != null)
                                presenterName = entity.Sale_Client.FirstOrDefault(p => p.Id == code.PresenterId).Name;

                            ar.PresenterName = presenterName;
                            ar.IsSuccess = true;

                            ar.LicenseCode = entity.Sale_Client.FirstOrDefault(p => p.Id == code.RegistrantId).LicenseCode;
                            ar.Period = code.Period;
                            ar.InvitedCodeQty = ActiveCodeUtil.DEFAULT_INVITED_CODE_QTY;//注册一次就提供5个激活码
                            ar.BeginTime = code.BeginTime;
                            ar.EndTime = code.EndTime;
                            ar.LicenseType = (int)code.Edition;
                            ar.Description = "注册成功";

                        }
                        else
                        {
                            ar.Description = message;
                        }
                    }
                }
                catch (Exception ex)
                {
                    tx.Rollback();
                    ar.Description = ex.StackTrace +Environment.NewLine+ ex.Message;
                }
            }

            return Newtonsoft.Json.JsonConvert.SerializeObject(ar);
        }

        public string GetInviteCodeQty(byte[] registrantInfoData, byte[] terminalInfoData)
        {
            throw new NotImplementedException();
        }

        public string GetInviteCode(byte[] registrantInfoData, byte[] terminalInfoData)
        {
            using(broker30Entities entity=new broker30Entities())
            {
                string msg = null;

                ResultInvitedCodeInfo result = new ResultInvitedCodeInfo();

                try
                {
                    RegistrantInfo registrantInfo = RegistrantInfo.Parse(registrantInfoData);

                    TerminalInfo terminalInfo = TerminalInfo.Parse(terminalInfoData);

                    bool isVerify = ClientUtil.VerifyLicense(registrantInfo, terminalInfo, entity,out msg);

                    if (isVerify)
                    {
                        Sale_Client client = entity.Sale_Client.FirstOrDefault(p => p.Name == registrantInfo.UserName);



                        if (client.InviteCodeQty > 0)
                        {
                            Sale_ActiveCode code = ClientUtil.GetInviteCode(client, entity);

                            if (code != null)
                            {
                                result.Code = code.Code;
                                result.Period = code.Period;
                                result.RegPeriod = code.RegPeriod;
                            }

                            result.Qty = client.InviteCodeQty.Value;
                            result.ReceiveTime = DateTimeUtil.ChinaStandardTime;
                            result.IsSuccess = true;

                        }
                    }
                    else
                    {
                        result.IsSuccess = false;
                        result.Description = msg;
                    }
                }
                catch (Exception er)
                {
                    result.Description = er.Message;
                    result.IsSuccess = false;
                }

                string s = Newtonsoft.Json.JsonConvert.SerializeObject(result);

                return s;
            }
        }

        public string GetClientScoreInfos(byte[] registrantInfoData, byte[] terminalInfoData)
        {
            throw new NotImplementedException();
        }

        public string GetClientInfo(byte[] registrantInfoData, byte[] terminalInfoData, long dataTs, long regTs)
        {
            RegistrantInfo registrantInfo = RegistrantInfo.Parse(registrantInfoData);

            TerminalInfo terminalInfo = TerminalInfo.Parse(terminalInfoData);

            using (broker30Entities entity = new broker30Entities())
            {
                ClientDataInfo cinfo = new ClientDataInfo();

                Record(registrantInfo.UserName, VisitTypeEnum.Connected, entity);

                long maxTx = GetServerLastStamp(entity).Ts;

                cinfo.IsNewData = maxTx > dataTs;

                string sql = string.Format("select isnull(cast(max(ts)as bigint),0) from Score_ScoreRecord as sr inner join sale_client as c on sr.ClientId =c.id where c.Name =N'{0}'", registrantInfo.UserName);

                long regMaxTs = entity.ExecuteStoreQuery<long>(sql, new string[] { registrantInfo.UserName }).FirstOrDefault();

                cinfo.IsNewReg = regMaxTs > regTs;

                sql = string.Format("select InviteCodeQty from sale_client where Name=N'{0}'", registrantInfo.UserName);

                cinfo.InviteQty = entity.ExecuteStoreQuery<int>(sql).FirstOrDefault(); 

                string result = Newtonsoft.Json.JsonConvert.SerializeObject(cinfo);

                return result;


            }
        }


        //public string GetProductMaxTs(byte[] registrantInfoData, byte[] terminalInfoData)
        //{
        //    throw new NotImplementedException();
        //}


        public string GetScoreRecord(byte[] registrantInfoData, byte[] terminalInfoData, long regTs)
        {

            using (broker30Entities entity = new broker30Entities())
            {

                try
                {
                    RegistrantInfo registrantInfo = RegistrantInfo.Parse(registrantInfoData);

                    TerminalInfo terminalInfo = TerminalInfo.Parse(terminalInfoData);

                    string sql = @"select
                                    ss.Id as id, 
                                    ss.OppositeLevel as OppositeLevel,
                                    c2.Name as ProviderName,
                                    isnull(cast(ss.Score as float),0) as  Score , 
                                    ss.ScoreTime as ScoreTime, 
                                    isnull(cast(ss.ts as bigint),0) as Ts
                                     
                                from Score_ScoreRecord as ss  
            	                    inner join Sale_client as c1 on ss.ClientId=c1.Id 
            	                    inner join Sale_client as c2 on ss.Providerid=c2.id
                                where c1.Name={0} and ss.Ts>{1}";


                    //IDbCommand cmd = entity.Connection.CreateCommand();
                    //cmd.CommandText = sql;

                    IList<ScoreRecordInfo> infos=entity.ExecuteStoreQuery<ScoreRecordInfo>(sql,new object[]{registrantInfo.UserName,regTs}).ToList<ScoreRecordInfo>();

                    string text = Newtonsoft.Json.JsonConvert.SerializeObject(infos);

                    return text;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }


        public string GetScoreRecordMaxTs(byte[] registrantInfoData, byte[] terminalInfoData)
        {
            using (broker30Entities entity = new broker30Entities())
            {
                
                RegistrantInfo registrantInfo = RegistrantInfo.Parse(registrantInfoData);

                TerminalInfo terminalInfo = TerminalInfo.Parse(terminalInfoData);

                long? maxTs = 0;

                if (ToolUtil.VerifyLicense(registrantInfo, terminalInfo, entity))
                {
                    string sql = "select ISNULL(CAST( MAX(Ts) as bigint),0) from Score_ScoreRecord as s inner join Sale_Client as c on s.ClientId=c.Id where c.Name=N'" + registrantInfo.UserName + "'";

                    maxTs= entity.ExecuteStoreQuery<long?>(sql).FirstOrDefault();

                }

                return Newtonsoft.Json.JsonConvert.SerializeObject(maxTs.Value);

            }
        }

        public string CheckLastTimeStamp(long ts)
        {
            using (broker30Entities entity = new broker30Entities())
            {
                string sql = "select max(LastTimeStamp) from System_TableUpdate where IsNeedUpdate=1 and TableType=0";

                long svrts = entity.ExecuteStoreQuery<long>(sql).FirstOrDefault();

                return Newtonsoft.Json.JsonConvert.SerializeObject(svrts > ts);
            }
        }

        public string UpdateTableData(string tableName, long minRow, long maxRow, long rowCount, long clientTs, string sqlWhere)
        {
            string connString = HttpContext.Current.Cache["SqlConnectionString"].ToString();

            using (SqlConnection cnn = new SqlConnection(connString))
            {
                try
                {
                    cnn.Open();
                    string sql = "select Name,TableType,SQL,IsNeedUpdate,Description,IsIdentity,LastTimeStamp from System_TableUpdate where name=@tableName";

                    SqlCommand cmd = cnn.CreateCommand();

                    cmd.CommandText = sql;
                    SqlParameter p = cmd.CreateParameter();
                    p.ParameterName = "@tableName";
                    p.DbType = DbType.String;
                    p.Value = tableName;
                    cmd.Parameters.Add(p);

                    SqlDataReader reader = cmd.ExecuteReader();


                    DBTableData td = null;
                    DBTable table = null;

                    if (reader.Read())
                    {
                        table = new DBTable();
                        table.Name = reader.GetString(0);
                        table.TableType = (TableType)reader.GetInt32(1);
                        table.SQL = reader.GetString(2);
                        table.IsNeedUpdate = reader.GetBoolean(3);
                        table.Description = reader.GetString(4);
                        table.IsIdentity = reader.GetBoolean(5);
                        table.LastTimeStamp = reader.GetInt64(6);

                        reader.Close();
                        td = table.LoadData(minRow, maxRow, rowCount, clientTs, sqlWhere, cnn);

                    }
                    else
                    {
                        td = new DBTableData();
                        td.IsSuccess = false;
                        td.Description = "不支持该表的更新!";
                    }

                    //reader.Close();
                    reader.Dispose();
                    cmd.Dispose();

                    string result = Newtonsoft.Json.JsonConvert.SerializeObject(td);

                    return result;
                }
                catch (Exception ex)
                {
                    throw ex;
                }

            }
        }

        private void Record(string name, VisitTypeEnum visitType,broker30Entities entity)
        {
            OperationContext context = OperationContext.Current;
            //获取传进的消息属性  
            System.ServiceModel.Channels.MessageProperties properties = context.IncomingMessageProperties;
            //获取消息发送的远程终结点IP和端口  
            System.ServiceModel.Channels.RemoteEndpointMessageProperty endpoint = properties[System.ServiceModel.Channels.RemoteEndpointMessageProperty.Name] as System.ServiceModel.Channels.RemoteEndpointMessageProperty;

            VisitRecordUtil.AddRecord(name, visitType, DateTimeUtil.ChinaStandardTime, endpoint.Address, entity);

        }

        private MaxTs GetServerLastStamp(broker30Entities entity)
        {
            try
            {
                //IDbCommand cmd = cnn.CreateCommand();

                long ts = entity.ExecuteStoreQuery<long>("select max(LastTimeStamp) from System_TableUpdate where IsNeedUpdate=1 and TableType=0").FirstOrDefault();

                //cmd.CommandText = "select max(LastTimeStamp) from System_TableUpdate where IsNeedUpdate=1 and TableType=0";

                //long ts = Convert.ToInt64(cmd.ExecuteScalar());

                MaxTs maxTimeStamp = new MaxTs();
                maxTimeStamp.Ts = ts;
                maxTimeStamp.LastLoadTime = DateTimeUtil.ChinaStandardTime;

                return maxTimeStamp;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
